package org.abbett.eskine.dao.inmemory;

import java.util.List;
import java.util.ArrayList;
import java.util.UUID;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import org.abbett.eskine.dao.UserDao;
import org.abbett.eskine.entity.User;

@Component("userDao")
public class InMemoryUserDao implements UserDao {
    private Map<Object, User> primaryIndex = new LinkedHashMap<Object, User>();

    @Override
    public void create(User user) {
        Object pk = user.primaryKey();
        if (pk == null) {
            pk = generatePrimaryKey();
            
            user.setId((String) pk);
        }

        primaryIndex.put(pk, user);
    }

    @PostConstruct
    public void init() {
        // initialize the db with some initial data
    }

    /**
     * The "Create" or "Update" semantics of "CRUD"
     */
    public void createOrUpdate(User user) {
        Object pk = user.primaryKey();
        if (pk == null || !primaryIndex.containsKey(pk)) {
            create(user);
        }
        else {
            update(user);
        }
    }

    /**
     * Find by Primary key
     * 
     * The "read" operation of CRUD
     */
    public User findByPrimaryKey(String key) {
        return primaryIndex.get(key);
    }

    public User findByUsernameAndPassword(String username, String password) {
        for (User user : primaryIndex.values()) {
            if (StringUtils.equals(user.getEmail(), username) 
                    && StringUtils.equals(user.getPassword(), password)) {
                return user;
            }
        }
        
        return null;
    }

    @Override
    public void delete(User user) {
        primaryIndex.remove(user.primaryKey());
    }

    @Override
    public void update(User user) {
        primaryIndex.put(user.primaryKey(), user);
    }


    /**
     * All Users. 
        				All users.
        			
     * 
     * The "read" operation of CRUD
     */
    public List<User> findUsers(Map<String, Object> params) {
        // TODO: implement your code here
        return new ArrayList<User>(primaryIndex.values());
    }

    @Override
    public User newInstance() {
        return new InMemoryUser();
    }
    

    /**
     * A scheme for generating new primary keys
     * 
     * @return
     *
     * @author Vineet Manohar
     */
    public Object generatePrimaryKey() {
        return UUID.randomUUID().toString();   
    }
}// clickframes::version=3164778412::clickframes